package com.jiangtour.service.impl;

import com.jiangtour.dataobject.*;
import com.jiangtour.dto.OrderDTO;
import com.jiangtour.dto.QueryOrderDTO;
import com.jiangtour.dto.SendInfoDTO;
import com.jiangtour.enums.OrderStatusEnum;
import com.jiangtour.enums.ResultEnum;
import com.jiangtour.enums.SendFlagEnum;
import com.jiangtour.exception.SiteException;
import com.jiangtour.repository.*;
import com.jiangtour.service.OrderService;
import com.jiangtour.service.SiteInfoService;
import com.jiangtour.utils.JsonUtil;
import com.jiangtour.utils.KeyUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @Title: OrderServiceImpl
 * @ProjectName site
 * @Description: TODO
 * @date 2018/12/28/02810:58
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMasterRepository orderMasterRepository;
    @Autowired
    private ConfigureCategoryRepository configureCategoryRepository;
    @Autowired
    private ProductCategoryRepository productCategoryRepository;
    @Autowired
    private SiteInfoRepository siteInfoRepository;
    @Autowired
    private SiteInfoService siteInfoService;


    @Override
    @Transactional
    public OrderDTO create(OrderDTO orderDTO) {
        String orderId = KeyUtil.getUniqueKey();
        OrderMaster orderMaster = new OrderMaster();
        orderDTO.setOrderId(orderId);
        BeanUtils.copyProperties(orderDTO, orderMaster);
        orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
        //根据规查询id
        if(orderMaster.getSpecId()!=null ){
            ProductCategory productCategory = productCategoryRepository.findById(orderMaster.getSpecId()).get();
            if(productCategory !=null ){
                orderMaster.setOrderAmount(productCategory.getCategoryAmount());
            }else {
                orderMaster.setOrderAmount(new BigDecimal(0.0));
            }
        }
        orderMaster.setUpdateTime(new Date());
        orderMaster.setCreateTime(new Date());
        orderMasterRepository.save(orderMaster);
        siteInfoService.saveOrUpdate(orderMaster);
        return orderDTO;
    }

    @Override
    public OrderDTO findOne(String orderId) {
        OrderMaster orderMaster = orderMasterRepository.findById(orderId).get();
        if (orderMaster == null) {
            throw new SiteException(ResultEnum.ORDER_NOT_EXIST);
        }
        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(orderMaster, orderDTO);

        return orderDTO;
    }

    @Override
    public Page<OrderDTO> findList(String ascriptionId, Pageable pageable) {
        Page<OrderMaster> page=  orderMasterRepository.findByAdditional(ascriptionId, pageable);
        return  null;
       // return new PageImpl<OrderDTO>(page.getContent(),pageable,page.getTotalElements());
    }

    @Override
    public OrderDTO cancel(OrderDTO orderDTO) {
        return null;
    }

    @Override
    public OrderDTO finish(OrderDTO orderDTO) {
        return null;
    }

    @Override
    public Page<OrderDTO> findList(Pageable pageable) {

        Page<OrderMaster> orderMasterPage=orderMasterRepository.findAll(pageable);
        List<OrderDTO> orderDTOList=OrderMaster2OrderDTOConverter(orderMasterPage.getContent());

        return new PageImpl<OrderDTO>(orderDTOList,pageable,orderMasterPage.getTotalElements());
    }

    @Override
    public Page<OrderDTO> findByList(Pageable pageable, QueryOrderDTO queryOrderDTO) {
        Page<OrderMaster> orderMasterPage= orderMasterRepository.findAll(new Specification<OrderMaster>() {
            @Override
            public Predicate toPredicate(Root<OrderMaster> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.conjunction();
                if(queryOrderDTO !=null){
                    if(null!= queryOrderDTO.getSpecId() && queryOrderDTO.getSpecId()!=-1){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("specId"),queryOrderDTO.getSpecId()));
                    }
                    if(null !=queryOrderDTO.getExpressCompany()&& queryOrderDTO.getExpressCompany()!=-2 && !StringUtils.isEmpty(queryOrderDTO.getExpressCompany())){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("expressCompany"),queryOrderDTO.getExpressCompany()));
                    }
                    if(null !=queryOrderDTO.getPhone()&& !StringUtils.isEmpty(queryOrderDTO.getPhone())){
                        predicate.getExpressions().add(criteriaBuilder.like(root.get("buyerPhone"),"%"+queryOrderDTO.getPhone()+"%"));
                    }
                    if (null !=queryOrderDTO.getPickUpParts() && queryOrderDTO.getPickUpParts()!=-1){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("pickUpParts"),queryOrderDTO.getPickUpParts()));
                    }
                    if(null !=queryOrderDTO.getAscriptionId()){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("ascriptionId"),queryOrderDTO.getAscriptionId()));
                    }
                    if (null!=queryOrderDTO.getType()){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("orderType"),queryOrderDTO.getType()));
                    }
                    if(null !=queryOrderDTO.getName() && !StringUtils.isEmpty(queryOrderDTO.getName())){
                        predicate.getExpressions().add(criteriaBuilder.like(root.get("buyerName"),"%"+queryOrderDTO.getName()+"%"));
                    }
                    if(null !=queryOrderDTO.getCreateTime() && !queryOrderDTO.getCreateTime().trim().equals("")){
                        predicate.getExpressions().add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(String.class),queryOrderDTO.getCreateTime()));
                    }

                }

                return predicate;
            }
        },pageable);

        List<OrderDTO> orderDTOList=OrderMaster2OrderDTOConverter(orderMasterPage.getContent());

        return new PageImpl<OrderDTO>(orderDTOList,pageable,orderMasterPage.getTotalElements());
    }

    @Override
    public List<OrderDTO> findAllExcel(QueryOrderDTO queryOrderDTO) {
       List<OrderMaster> list=   orderMasterRepository.findAll(new Specification<OrderMaster>() {
            @Override
            public Predicate toPredicate(Root<OrderMaster> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.conjunction();
                if(queryOrderDTO !=null){
                    if(null!= queryOrderDTO.getSpecId() && queryOrderDTO.getSpecId()!=-1){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("specId"),queryOrderDTO.getSpecId()));
                    }
                    if(null !=queryOrderDTO.getExpressCompany() && queryOrderDTO.getExpressCompany()!=-2 && !StringUtils.isEmpty(queryOrderDTO.getExpressCompany()) ){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("expressCompany"),queryOrderDTO.getExpressCompany()));
                    }
                    if(null !=queryOrderDTO.getPhone() &&  !StringUtils.isEmpty(queryOrderDTO.getPhone())){
                        predicate.getExpressions().add(criteriaBuilder.like(root.get("buyerPhone"),"%"+queryOrderDTO.getPhone()+"%"));
                    }
                    if (null !=queryOrderDTO.getPickUpParts()  && queryOrderDTO.getPickUpParts()!=-1){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("pickUpParts"),queryOrderDTO.getPickUpParts()));
                    }
                    if(null !=queryOrderDTO.getAscriptionId()){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("ascriptionId"),queryOrderDTO.getAscriptionId()));
                    }
                    if (null!=queryOrderDTO.getType()){
                        predicate.getExpressions().add(criteriaBuilder.equal(root.get("orderType"),queryOrderDTO.getType()));
                    }
                    if(null !=queryOrderDTO.getCreateTime() && !queryOrderDTO.getCreateTime().trim().equals("")){
                        predicate.getExpressions().add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(String.class),queryOrderDTO.getCreateTime()));
                    }

                }

                return predicate;
            }
        });

        List<OrderDTO> orderDTOList=OrderMaster2OrderDTOConverter(list);

        return  orderDTOList;
    }

    //实体装换
    private List<OrderDTO> OrderMaster2OrderDTOConverter(List<OrderMaster> content) {
        return content.stream().map(e->convert(e)).collect(Collectors.toList());
    }

    public  OrderDTO convert(OrderMaster orderMaster) {

        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(orderMaster, orderDTO);
       //取件点
        if(orderDTO!=null && orderDTO.getPickUpParts()!=null){
            ConfigureCategory pickUpParts = configureCategoryRepository.findById(orderDTO.getPickUpParts()).get();
            orderDTO.setPickUpPartsName(pickUpParts.getCategoryName()!=null?pickUpParts.getCategoryName():"");
        }

        //归属
        if(orderDTO !=null && orderDTO.getAscriptionId()!=null){
            SiteInfo siteInfo = siteInfoRepository.findById(orderDTO.getAscriptionId()).get();
            orderDTO.setAscriptionId(siteInfo.getSiteName()!=null?siteInfo.getSiteName():"");
        }

        //规格
        if(orderDTO !=null && orderDTO.getSpecId()!=null ){
            ProductCategory productCategory = productCategoryRepository.findById(orderDTO.getSpecId()).get();
            orderDTO.setSpecName(productCategory.getCategoryName()!=null?productCategory.getCategoryName():"");
        }

        //快递公司
        if(orderDTO!=null && orderDTO.getExpressCompany()!=null){
            if(orderDTO.getExpressCompany()== -1){
                orderDTO.setExpressName("不限快递公司");
            }else {
                ConfigureCategory expressCompany = configureCategoryRepository.findById(orderDTO.getExpressCompany()).get();
                if(expressCompany !=null ){
                    orderDTO.setExpressName(expressCompany.getCategoryName()!=null?expressCompany.getCategoryName():"");
                }
            }


        }
        //取件信息 代寄和代收区别
        if(orderDTO.getAdditional()!=null && !StringUtils.isEmpty(orderDTO.getAdditional())){
            SendInfoDTO  sendInfoDTO = (SendInfoDTO) JsonUtil.JSONToObject(orderDTO.getAdditional(), SendInfoDTO.class);
            if(null !=sendInfoDTO ){
                if(sendInfoDTO.getAdditionalInfo()!=null && !StringUtils.isEmpty(sendInfoDTO.getAdditionalInfo()) && orderDTO.getOrderType()==SendFlagEnum.COLLECT.getCode()){
                            orderDTO.setAdditionalInfo(sendInfoDTO.getAdditionalInfo());
                }
                //代寄件
                if(orderDTO.getOrderType()==SendFlagEnum.SEND.getCode()){
                    orderDTO.setAddressee(sendInfoDTO.getAddressee()!=null?sendInfoDTO.getAddressee():"");
                    orderDTO.setAddresseeAddress(sendInfoDTO.getAddresseePhone()!=null?sendInfoDTO.getAddresseePhone():"");
                    orderDTO.setAddresseePhone(sendInfoDTO.getAddresseeAddress()!=null ?sendInfoDTO.getAddresseeAddress():"");
                }

            }

        }

        return orderDTO;
    }

}
